package com.ship.dispatch.controller.decisionAnalysis;

import cn.hutool.core.io.resource.InputStreamResource;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ship.common.core.base.Page;
import com.ship.common.core.constant.ShipApiConstants;
import com.ship.common.core.domain.R;
import com.ship.common.core.exception.BusException;
import com.ship.common.core.exception.ServiceException;
import com.ship.common.core.utils.FileUtils;
import com.ship.common.core.utils.OkHttpUtil;
import com.ship.common.core.utils.StringUtils;
import com.ship.common.core.web.controller.BaseController;
import com.ship.common.core.web.domain.BaseResultCode;
import com.ship.common.core.web.domain.JsonResult;
import com.ship.common.log.annotation.Log;
import com.ship.common.log.enums.BusinessType;
import com.ship.common.security.utils.SecurityUtils;
import com.ship.dispatch.bean.decisionAnalysis.SmShipRent;
import com.ship.dispatch.bean.fob.SpFobFileRecord;
import com.ship.dispatch.bo.SmShipRentAnalysisBo;
import com.ship.dispatch.bo.SmShipRentBrokerAddBo;
import com.ship.dispatch.bpm.utils.CalculateDateUtil;
import com.ship.dispatch.model.Vo.SmShipRentAnalysisFormatVo;
import com.ship.dispatch.model.Vo.SmShipRentAnalysisVo;
import com.ship.dispatch.model.dto.shipReport.SaveShipReportDto;
import com.ship.dispatch.service.ExportService;
import com.ship.dispatch.service.decisionAnalysis.SmShipRentService;
import com.ship.dispatch.service.fob.SpFobFileRecordService;
import com.ship.system.api.RemoteFileService;
import com.ship.system.api.domain.SysFile;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import okhttp3.*;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.*;

@RestController
@RequestMapping("/shipRent/")
@Api(value = "shipRent", tags = "船舶租金")
public class ShipRentController {
    @Autowired
    private SmShipRentService shipRentService;
    @Autowired
    SpFobFileRecordService spFobFileRecordService;
//    @Value("${file_server.host}")
//    private String fileServerHost;
//    @Value("${file_server.temp}")
//    private String tempFileUrl;
    private static final String FILE_UPLOAD_PATH = "/group1/upload";

    @Autowired
    private RemoteFileService remoteFileService;


    /**
     * 删除船舶租金附件
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "删除船舶租金附件")
    @DeleteMapping("/deleteFile/{id}")
    @Log(title = "删除船舶租金附件", businessType = BusinessType.DELETE)
    public JsonResult deleteFile(@PathVariable("id") Long id) {
        spFobFileRecordService.removeById(id);
        return JsonResult.success();
    }

    @ApiOperation(value = "导入船舶租金")
    @PostMapping("/uploadShipRent")
    @Log(title = "导入船舶租金", businessType = BusinessType.IMPORT)
    public JsonResult uploadShipRent(@RequestParam("file") MultipartFile file) {
        FileUtils.checkFileName(file);
        try {
            R<SysFile> result = remoteFileService.upload(file);
            if(result.getCode() != R.SUCCESS){
                throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
            }
            SpFobFileRecord spFobFileRecord = new SpFobFileRecord();
            spFobFileRecord.setPath(result.getData().getHttpsUrl());
            spFobFileRecord.setHttpPath(result.getData().getHttpUrl());
            spFobFileRecord.setName(file.getName());
            spFobFileRecord.setFileType("船舶租金");
            spFobFileRecord.setCreateDate(new Date());
            spFobFileRecord.setCreateBy(SecurityUtils.getStringUserId());
            spFobFileRecordService.save(spFobFileRecord);
            return JsonResult.success(String.valueOf(spFobFileRecord.getId()));
        } catch (Exception e) {
            return JsonResult.failed("上传失败，原因：" + e.getMessage());
        }
    }

    /**
     * 导入保存船舶租金
     *
     * @param shipReportDto
     * @return
     */
    @ApiOperation(value = "导入保存船舶租金")
    @PostMapping("saveShipRent")
    @Log(title = "导入保存船舶租金",businessType = BusinessType.INSERT)
    public JsonResult saveShipRent(@RequestBody SaveShipReportDto shipReportDto) {
        if (null != shipReportDto.getIds() && shipReportDto.getIds().size() > 0) {
            List<SpFobFileRecord> fileRecords = spFobFileRecordService.listByIds(shipReportDto.getIds());
            if (null != fileRecords && fileRecords.size() > 0) {
                fileRecords.stream().forEach(f -> {
                    shipRentService.saveShipRent(f);
                });
            }
            return JsonResult.success();
        } else {
            return JsonResult.failed("无附件，请核实");
        }
    }


    @Autowired
    private ExportService exportService;

    /**
     * VesselType方式新增船舶租金
     *
     * @param shipRent
     * @return
     */
    @ApiOperation(value = "VesselType方式新增船舶租金")
    @PostMapping("add/vessel")
    @Log(title = "VesselType方式新增船舶租金", businessType = BusinessType.INSERT)
    public JsonResult addByVesselType(@RequestBody SmShipRent shipRent) {
        return JsonResult.success(shipRentService.addByVesselType(shipRent));
    }

    /**
     * 租金数据校验
     *
     * @param shipRent
     * @return 校验对象为null 则返回false不存在，返回true 存在
     */
    @ApiOperation(value = "租金数据校验")
    @PostMapping("checkRentData")
    @Log(title = "租金数据校验", businessType = BusinessType.OTHER)
    public JsonResult checkRentData(@RequestBody SmShipRent shipRent) {
        return JsonResult.success(shipRentService.checkRentDataNew(shipRent));
    }

    /**
     * Broker方式新增船舶租金
     *
     * @param addBo
     * @return
     */
    @ApiOperation(value = "Broker方式新增船舶租金")
    @PostMapping("add/broker")
    @Log(title = "Broker方式新增船舶租金", businessType = BusinessType.INSERT)
    public JsonResult addByBroker(@RequestBody SmShipRentBrokerAddBo addBo) {
        return shipRentService.addByBroker(addBo);
    }

    /**
     * 船舶租金分页
     *
     * @param shipRent
     * @return
     */
    @ApiOperation(value = "船舶租金分页")
    @PostMapping("page")
    public JsonResult<Page<SmShipRent>> page(@RequestBody SmShipRent shipRent) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        if(shipRent.getRentWeekTest() != null){
            queryWrapper.apply("YEAR(rent_date) = {0}", CalculateDateUtil.getYears(shipRent.getRentWeekTest()));
        }
        queryWrapper.orderByDesc("rent_date");
        Page<SmShipRent> page = shipRentService.page(shipRent, queryWrapper);
        return JsonResult.success(page);
    }

    /**
     * 船舶租金分页导出
     *
     * @return
     */
    @ApiOperation(value = "船舶租金分页导出")
    @PostMapping("page/export")
    @Log(title = "船舶租金分页导出", businessType = BusinessType.EXPORT)
    public JsonResult pageExport(@RequestBody SmShipRent shipRent) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        if (shipRent.getIds() != null && shipRent.getIds().size() > 0) {
            queryWrapper.in("id", shipRent.getIds());
        }
        List<SmShipRent> exportList = shipRentService.pageExportList(shipRent, queryWrapper, new LinkedList<>());
        for (SmShipRent smShipRent : exportList) {
            smShipRent.setRentSixMonthStr(smShipRent.getRentSixMonthStr());
            smShipRent.setRentTwelveMonthStr(smShipRent.getRentTwelveMonthStr());
            smShipRent.setRentThirtySixMonthStr(smShipRent.getRentThirtySixMonthStr());
            smShipRent.setRentSixtyMonthStr(smShipRent.getRentSixtyMonthStr());
            smShipRent.setRentHundredTwentyMonthStr(smShipRent.getRentHundredTwentyMonthStr());
            smShipRent.setVesselTypeStr(smShipRent.getVesselTypeStr());
            smShipRent.setSpotEastStr(smShipRent.getSpotEastStr());
            smShipRent.setSpotWestStr(smShipRent.getSpotWestStr());
            smShipRent.setSpotMiddleEastStr(smShipRent.getSpotMiddleEastStr());
        }
        Field[] fields = SmShipRent.class.getDeclaredFields();
        String url = exportService.pageExport(exportList, fields, exportService.listStrByModuleAndUser
                ("sm_ship_rent", SecurityUtils.getUserId()), "船舶租金信息");
        return JsonResult.success(url);
    }

    /**
     * 删除船舶租金
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "删除船舶租金")
    @DeleteMapping("/deleteShipRent/{id}")
    @Log(title = "删除船舶租金", businessType = BusinessType.DELETE)
    public JsonResult deleteShipRent(@PathVariable("id") Long id) {
        shipRentService.removeById(id);
        return JsonResult.success();
    }

    /**
     * 修改船舶租金
     *
     * @param shipRent
     * @return
     */
    @ApiOperation(value = "修改船舶租金")
    @PostMapping("updateShipRent")
    @Log(title = "修改船舶租金", businessType = BusinessType.UPDATE)
    public JsonResult updateShipRent(@RequestBody SmShipRent shipRent) {
        SmShipRent shipReport = shipRentService.updateShipRent(shipRent);
        return JsonResult.success(shipReport);
    }

    /**
     * 租金汇总左侧菜单
     *
     * @return
     */
    @ApiOperation(value = "租金汇总左侧菜单")
    @GetMapping("summary/menu/tree")
    public JsonResult summaryMenuTree() {
        return shipRentService.summaryMenuTree();
    }

    /**
     * 租金汇总
     *
     * @param key
     * @param type
     * @return
     */
    @ApiOperation(value = "租金汇总")
    @GetMapping("summary/list")
    public JsonResult summaryBroker(@RequestParam(value = "key") String key, @RequestParam(value = "type") String type) {
        return JsonResult.success(shipRentService.summaryList(key, type));
    }

    /**
     * 租金汇总导出
     *
     * @param key
     * @param type
     * @return
     */
    @ApiOperation(value = "租金汇总导出")
    @GetMapping("summary/list/export")
    @Log(title = "租金汇总导出", businessType = BusinessType.EXPORT)
    public JsonResult summaryBrokerExport(@RequestParam(value = "key") String key, @RequestParam(value = "type") String type) throws IOException {
        return shipRentService.summaryListExport(key, type);
    }

    /**
     * 租金分析表格列表
     *
     * @param analysisBo
     * @return
     */
    @ApiOperation(value = "租金分析表格列表")
    @PostMapping("analysis/list")
    public JsonResult<List<SmShipRentAnalysisVo>> analysisList(@RequestBody SmShipRentAnalysisBo analysisBo) {
        return shipRentService.analysisList(analysisBo);
    }

    /**
     * 租金分析表格列表导出
     *
     * @param analysisBo
     * @return
     */
    @ApiOperation(value = "租金分析表格列表导出")
    @PostMapping("analysis/list/export")
    public JsonResult analysisListExport(@RequestBody SmShipRentAnalysisBo analysisBo) throws IOException {
        return shipRentService.analysisListExport(analysisBo);
    }

    /**
     * 租金分析统计图
     *
     * @param analysisBo
     * @return
     */
    @ApiOperation(value = "租金分析统计图")
    @PostMapping("analysis/statistics")
    public JsonResult<List<SmShipRentAnalysisFormatVo>> analysisStatistics(@RequestBody SmShipRentAnalysisBo analysisBo) {
        return shipRentService.analysisStatistics(analysisBo);
    }
}
